package com.johnsoft.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import com.johnsoft.pph.InstallerThread;
import com.johnsoft.pph.Setup;

public class ZIP {
	
	public static void packData(File folder, String filename) {
		try {
			ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(new File(filename)));
			
			String[] files = folder.list();
			if(files == null) {
				zip.close();
				return;
			}
			for(int i = 0; i < files.length; i++) {
				packFile(new File(folder.getAbsoluteFile() + "\\" + files[i]), zip, folder.getName());
			}
			zip.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void packFile(File f, ZipOutputStream zip, String folderName) {
		packFile(f, zip, folderName, new File("").getAbsolutePath().length() + folderName.length() + 2);
	}
	
	private static void packFile(File f, ZipOutputStream zip, String folderName, int subStringSize) {
		try {
			if(f.isDirectory()) {
				String[] files = f.list();
				if(files == null)
					return;
				for (int i = 0; i < files.length; i++) {
					packFile(new File(folderName + "\\" + f.getName() + "\\" + files[i]), zip, folderName + "\\" + f.getName(), subStringSize);
				}
			} else { //Normal File
				String zipFile = f.getAbsolutePath().substring(subStringSize);
				zip.putNextEntry(new ZipEntry(zipFile));
				byte[] bytes = Setup.readFile(f);
				System.out.println("Compressing: " + zipFile);
				zip.write(bytes, 0, bytes.length);
				zip.closeEntry();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void createDirs(String s) {
		if(s.endsWith("null") || s.endsWith("pph"))
			return;
		if(s.contains(".")) {
			if(!s.endsWith("\\"))
				s = s.substring(0, s.lastIndexOf("\\"));
		}
		if(new File(s).exists()) {
			return;
		}
		System.out.print("Creating Dirs for: " + s);
		while(!new File(s).mkdirs()) { InstallerThread.Sleep(100); }
		System.out.println(" Done");
	}
	
	public static void deleteFolder(File folder) {
		if(!folder.exists()) 
			return;
		String[] files = folder.list();
		if(files == null) {
			folder.delete();
			return;
		}
		for(int i = 0; i < files.length; i++) {
			File file = new File(folder.getAbsolutePath() + "\\" + files[i]);
			if(file.isDirectory())
				deleteFolder(file);
			else
				file.delete();
		}
		folder.delete();
	}
	
	public static void unpackData(File file, File folder) throws IOException {
		if(folder.exists())
			deleteFolder(folder);
		folder.mkdirs();
		ZipInputStream zip = new ZipInputStream(new FileInputStream(file));
		//As long there are zipped files: Unpack'm
		ZipEntry entry;
		while ((entry = zip.getNextEntry()) != null) {
			File extract = new File(folder.getAbsolutePath() + "\\" + entry.getName());
			//Skip Folder Names (aka: extensionless files)
			if(!entry.getName().contains(".") && entry.getName() != "null") {
				System.out.println("Skipping: " + extract.getAbsolutePath());
				zip.closeEntry();
				continue;
			}
			System.out.println("Extracting: " + extract.getAbsolutePath());
			createDirs(extract.getAbsolutePath());
			FileOutputStream destFile = new FileOutputStream(extract);
			byte[] buffer = new byte[1024];
			int written = 0;
			while((written = zip.read(buffer)) > 0) {
				destFile.write(buffer, 0, written);
			}
			destFile.close();
			zip.closeEntry();
			InstallerThread.Sleep(1);
		}
		zip.close();
	}

}
